From f1d4a077eaec3badf15998ba20b9315eeebfe8b5 Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Tue, 15 Nov 2005 17:22:04 +0100 Subject: [PATCH] Fix race between xspy_read_watch and xspy_watch, by placing the watch in the xshandle's list of watches *before* registering the watch with Xend. Closes bug #392. Signed-off-by: Ewan Mellor --- tools/python/xen/lowlevel/xs/xs.c | 53 +++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 17 deletions(-) diff --git a/tools/python/xen/lowlevel/xs/xs.c b/tools/python/xen/lowlevel/xs/xs.c index 6f195437a7..5a72eaeb46 100644 --- a/tools/python/xen/lowlevel/xs/xs.c +++ b/tools/python/xen/lowlevel/xs/xs.c @@ -16,7 +16,7 @@ * * Copyright (C) 2005 Mike Wray Hewlett-Packard * Copyright (C) 2005 Christian Limpach - * + * Copyright (C) 2005 XenSource Ltd. */ #include @@ -453,25 +453,20 @@ static PyObject *xspy_watch(PyObject *self, PyObject *args, PyObject *kwds) XsHandle *xsh = (XsHandle *)self; struct xs_handle *xh = xshandle(self); - PyObject *val = NULL; int xsval = 0; if (!xh) - goto exit; + return NULL; if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path, &token)) - goto exit; - Py_INCREF(token); - sprintf(token_str, "%li", (unsigned long)token); - Py_BEGIN_ALLOW_THREADS - xsval = xs_watch(xh, path, token_str); - Py_END_ALLOW_THREADS - if (!xsval) { - PyErr_SetFromErrno(PyExc_RuntimeError); - Py_DECREF(token); - goto exit; - } + return NULL; + + /* Note that we have to store the watch token in the xs->watches list + before registering the watch with xs_watch, otherwise this function + races with xs_read_watch. + */ + Py_INCREF(token); for (i = 0; i < PyList_Size(xsh->watches); i++) { if (PyList_GetItem(xsh->watches, i) == Py_None) { PyList_SetItem(xsh->watches, i, token); @@ -480,10 +475,26 @@ static PyObject *xspy_watch(PyObject *self, PyObject *args, PyObject *kwds) } if (i == PyList_Size(xsh->watches)) PyList_Append(xsh->watches, token); + + sprintf(token_str, "%li", (unsigned long)token); + Py_BEGIN_ALLOW_THREADS + xsval = xs_watch(xh, path, token_str); + Py_END_ALLOW_THREADS + if (!xsval) { + for (i = 0; i < PyList_Size(xsh->watches); i++) { + if (PyList_GetItem(xsh->watches, i) == token) { + Py_INCREF(Py_None); + PyList_SetItem(xsh->watches, i, Py_None); + break; + } + } + + PyErr_SetFromErrno(PyExc_RuntimeError); + return NULL; + } + Py_INCREF(Py_None); - val = Py_None; - exit: - return val; + return Py_None; } #define xspy_read_watch_doc "\n" \ @@ -944,3 +955,11 @@ PyMODINIT_FUNC initxs (void) module = Py_InitModule(PYPKG, xs_methods); } + + +/* + * Local variables: + * c-indent-level: 4 + * c-basic-offset: 4 + * End: + */ -- 2.30.2